/*
 * alu.h
 *
 *  Created on: Jan 21, 2013
 *      Author: Ian Smith, Travis Drake
 */

#ifndef ALU_H_
#define ALU_H_

#include "register.h"

/*
 * Represents and ALU object.
 */
typedef struct {
	RegisterPtr operand_a;
	RegisterPtr operand_b;
	RegisterPtr result_r;
	RegisterPtr result_r2;
	Bit status_n;
	Bit status_z;
	Bit status_c;
	Bit status_o;
} AluStr;

/*
 * A pointer to an ALU object.
 */
typedef AluStr* AluPtr;


/*
 * Initializes a new ALU object.
 */
AluPtr alu_new_alu(void);

/*
 * Frees the given ALU object.
 * alu: The ALU object to free.
 */
void alu_free(AluPtr alu);


/*
 * Sets input operand A on the given ALU.
 * alu: The ALU object to set the input operand of.
 * value: The new value to set.
 */
void alu_set_operand_a(AluPtr alu, unsigned short value);

/*
 * Sets input operand B on the given ALU.
 * alu: The ALU object to set the input operand of.
 * value: The new value to set.
 */
void alu_set_operand_b(AluPtr alu, unsigned short value);

/*
 * Gets the result of the last ALU operation.
 * alu: The ALU object to get the result of.
 */
unsigned short alu_get_result_r(AluPtr alu);

/*
 * Gets the remainder result of the last ALU operation.
 * alu: The ALU object to get the remainder result of.
 */
unsigned short alu_get_result_r2(AluPtr alu);


/*
 * Gets the N (negative) status bit for the last ALU operation.
 * alu: The ALU object to get the status of.
 */
Bit alu_get_status_n(AluPtr alu);

/*
 * Gets the Z (zero) status bit for the last ALU operation.
 * alu: The ALU object to get the status of.
 */
Bit alu_get_status_z(AluPtr alu);

/*
 * Gets the C (carry) status bit for the last ALU operation.
 * alu: The ALU object to get the status of.
 */
Bit alu_get_status_c(AluPtr alu);

/*
 * Gets the O (overflow) status bit for the last ALU operation.
 * alu: The ALU object to get the status of.
 */
Bit alu_get_status_o(AluPtr alu);


/*
 * Performs an addition operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_add(AluPtr alu);

/*
 * Performs a subtraction operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_sub(AluPtr alu);

/*
 * Performs a multiplication operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_mul(AluPtr alu);

/*
 * Performs a division operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_div(AluPtr alu);


/*
 * Performs a logical AND operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_and(AluPtr alu);

/*
 * Performs a logical OR operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_or(AluPtr alu);

/*
 * Performs a logical XOR operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_xor(AluPtr alu);

/*
 * Performs a logical NOT operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_not(AluPtr alu);


/*
 * Performs a shift-left operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_shl(AluPtr alu);

/*
 * Performs a shift-right operation with the two operands in the ALU.
 * alu: The ALU object to perform the operation on.
 */
void alu_shr(AluPtr alu);

#endif /* ALU_H_ */
